home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 6 / develop 6 code / TCP / NewsWatcher / NewsWatcher 2.0d15 source / source / header.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-30  |  4.8 KB  |  206 lines  |  [TEXT/KAHL]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     header.c
  4.  
  5.     This module handles the Show/Hide Header command, and
  6.     contains some utilities for dealing with headers.
  7.     
  8.     Portions copyright © 1990, Apple Computer.
  9.     Portions copyright © 1993, Northwestern University.
  10.  
  11. ----------------------------------------------------------------------------*/
  12.  
  13. #include <string.h>
  14.  
  15. #include "glob.h"
  16. #include "header.h"
  17. #include "menus.h"
  18. #include "resize.h"
  19. #include "scroll.h"
  20. #include "util.h"
  21. #include "wind.h"
  22.  
  23.  
  24. /*    FindHeader - search the header part of a message for some header.
  25. */
  26.  
  27. Boolean FindHeader (Handle text, const char *hdr, char *contents, 
  28.     short maxLength)
  29. {
  30.     long hdrLen, hdrEnd;
  31.     char *p, *pEnd, *q;
  32.     short len;
  33.  
  34.     *contents = 0;
  35.     hdrLen = strlen(hdr);
  36.     hdrEnd = Munger(text,0,CRCR,2,nil,0);
  37.     if (hdrEnd < 0) return false;
  38.     p = *text;
  39.     pEnd = *text + hdrEnd;
  40.     while (p < pEnd) {
  41.         if (strncasecmp(p, hdr, hdrLen) == 0) {
  42.             p += hdrLen;
  43.             while (p < pEnd && *p == ' ') p++;
  44.             q = p;
  45.             while (q < pEnd && *q != CR) q++;
  46.             q--;
  47.             while (q > p && *q == ' ') q--;
  48.             q++;
  49.             len = q-p;
  50.             if (len == 0 || len >= maxLength) return false;
  51.             strncpy(contents, p, len);
  52.             contents[len] = 0;
  53.             return true;
  54.         }
  55.         while (p < pEnd && *p != CR) p++;
  56.         p++;
  57.     }
  58.     return false;
  59. }
  60.  
  61. /* PrettifyName extracts the author's name from the "From" text.
  62.  *    The new "prettified" name replaces the old one.
  63.  *    Returns the length of the prettified name. 
  64.  */
  65. short PrettifyName (char *name)
  66. {
  67.     char *p, *start = 0, *end = 0;
  68.     short len, oldlen;
  69.  
  70.     oldlen = strlen(name);
  71.     end = name + oldlen - 1;
  72.  
  73.     /* Find the first < or ( in the name */
  74.     p = name;
  75.     while (*p && *p != '(' && *p != '<') p++;
  76.     if (*p == '(') {                 /* format = "address (name)" */
  77.         while (*p) {
  78.             if (*p == '(') {
  79.                 start = p+1;        /* Handle (illegal) nested parens */
  80.             } else if (*p == ')') {
  81.                 end = p - 1;
  82.                 break;
  83.             }
  84.             p++;
  85.         }
  86.     } else {                         /* format = "name <address>" or "address" */
  87.         if (*p == '<')
  88.             p++;
  89.         start = p;
  90.         while (*p && *p != '>') p++;
  91.         end = p - 1;
  92.     }
  93.     if (start && end >= start) {
  94.         while (start < end && *start == ' ') start++;
  95.         while (start < end && *end == ' ') end--;
  96.         len = end - start + 1;
  97.         BlockMove(start, name, len);
  98.         name[len] = 0;
  99.         return len;
  100.     }
  101.     return oldlen;
  102. }
  103.  
  104.  
  105. /*    GetAuthorFromHeader extracts the author's name from an article.
  106. */
  107.  
  108. void GetAuthorFromHeader (Handle text, char *author)
  109. {
  110.     FindHeader(text, "From:", author, 255);
  111.     PrettifyName(author);
  112. }
  113.  
  114.  
  115.  
  116. /*    FindBody returns the offset in article or message text of the first character of the 
  117.     article or message body. It skips past the header and any empty lines following the
  118.     header.
  119. */
  120.  
  121. long FindBody (Handle text)
  122. {
  123.     char *p, *pEnd;
  124.     long length;
  125.     
  126.     length = GetHandleSize(text);
  127.     p = *text;
  128.     pEnd = p + length;
  129.     while (p < pEnd) {
  130.         if (*p == CR && *(p+1) == CR) break;
  131.         p++;
  132.     }
  133.     p += 2;
  134.     return p < pEnd ? p-*text : length;
  135. }
  136.  
  137.  
  138. /*    DoShowHideHeader shows or hides the header in an article or message window.
  139. */
  140.  
  141. void DoShowHideHeader (WindowPtr wind)
  142. {
  143.     TWindow **info;
  144.     ControlHandle scrollBar;
  145.     Boolean headerShown;
  146.     short numSections;
  147.     TEHandle theTE;
  148.     Handle text;
  149.     long length, headerLength;
  150.     EWindowKind kind;
  151.     
  152.     info = (TWindow**)GetWRefCon(wind);
  153.     kind = (**info).kind;
  154.     theTE = (**info).theTE;
  155.     headerShown = (**info).headerShown = !(**info).headerShown;
  156.     SetItem(GetMHandle(kEditMenu),kShowHideHeaderItem,
  157.         headerShown ? "\pHide Header" : "\pShow Header");
  158.     if (kind == kArticle || kind == kMiscArticle) { /* article window */
  159.         numSections = (**info).numSections;
  160.         scrollBar = numSections > 1 ? HScrollCont(wind) : VScrollCont(wind);
  161.         SetCtlValue(scrollBar, 0);
  162.         MoveText(wind, scrollBar);
  163.         if (numSections > 1) return;
  164.         text = (**info).fullText;
  165.         if (headerShown) {
  166.             length = GetHandleSize(text);
  167.             HLock(text);
  168.             TESetText(*text,length,theTE);
  169.             HUnlock(text);
  170.             TESetSelect(0,0,theTE);
  171.             AdjustScrollBar(wind);
  172.             (**theTE).destRect = (**theTE).viewRect;
  173.             EraseRect(&(**theTE).destRect);
  174.             TEUpdate(&(**theTE).destRect,theTE);
  175.         } else {
  176.             TESetSelect(0, FindBody(text), theTE);
  177.             TEDelete(theTE);
  178.             AdjustScrollBar(wind);
  179.         }
  180.     } else { /* message window */
  181.         scrollBar = VScrollCont(wind);
  182.         SetCtlValue(scrollBar, 0);
  183.         MoveText(wind, scrollBar);
  184.         if (headerShown) {
  185.             text = (**info).headerText;
  186.             length = GetHandleSize(text);
  187.             TESetSelect(0, 0, theTE);
  188.             HLock(text);
  189.             TEInsert(*text, length, theTE);
  190.             TESetSelect(length, length, theTE);
  191.             HUnlock(text);
  192.         } else {
  193.             text = (Handle)TEGetText(theTE);
  194.             headerLength = FindBody(text);
  195.             if ((**info).headerText == nil) (**info).headerText = MyNewHandle(0);
  196.             HLock(text);
  197.             PtrToXHand(*text, (**info).headerText, headerLength);
  198.             HUnlock(text);
  199.             TESetSelect(0, headerLength, theTE);
  200.             TEDelete(theTE);
  201.         }
  202.         AdjustScrollBar(wind);
  203.     }
  204.     SetWindowNeedsZooming(wind);
  205. }
  206.